package cn.com.anypay.manager.service.auth.factory;

import cn.com.anypay.manager.service.auth.strategy.IAuthStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 认证策略工厂
 * 负责管理和提供各种认证策略
 */
@Slf4j
@Component
public class AuthStrategyFactory {

    /**
     * 策略映射表
     */
    private final Map<String, IAuthStrategy> strategyMap = new HashMap<>();

    /**
     * 所有认证策略（Spring自动注入）
     */
    @Autowired
    private List<IAuthStrategy> strategies;

    /**
     * 初始化策略映射
     */
    @PostConstruct
    public void init() {
        log.info("开始初始化认证策略工厂");

        strategies.forEach(strategy -> {
            String authType = strategy.getAuthType();
            strategyMap.put(authType, strategy);
            log.info("注册认证策略: {} -> {}", authType, strategy.getClass().getSimpleName());
        });

        log.info("认证策略工厂初始化完成，共注册{}个策略", strategyMap.size());
    }

    /**
     * 获取指定类型的认证策略
     *
     * @param authType 认证类型
     * @return 认证策略
     * @throws IllegalArgumentException 如果认证类型不支持
     */
    public IAuthStrategy getStrategy(String authType) {
        if (authType == null || authType.trim().isEmpty()) {
            throw new IllegalArgumentException("认证类型不能为空");
        }

        IAuthStrategy strategy = strategyMap.get(authType);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的认证类型: " + authType);
        }

        return strategy;
    }

    /**
     * 检查是否支持指定的认证类型
     *
     * @param authType 认证类型
     * @return true-支持，false-不支持
     */
    public boolean isSupported(String authType) {
        return authType != null && strategyMap.containsKey(authType);
    }

    /**
     * 获取所有支持的认证类型
     *
     * @return 支持的认证类型集合
     */
    public Set<String> getSupportedAuthTypes() {
        return strategyMap.keySet();
    }

    /**
     * 获取策略数量
     *
     * @return 策略数量
     */
    public int getStrategyCount() {
        return strategyMap.size();
    }
}